const MaxHeap = require('../heap/maxHeap');
const Comparator = require('../utils/Comparator');

module.exports = class PriorityQueue extends MaxHeap {
  constructor() {
    super();
    // 存储每个item对应的priority
    this.priorities = new Map();
    this.compare = new Comparator(this.comparePriority.bind(this));
  }
  add(item, priority = 0) {
    this.priorities.set(item, priority);
    // 调用heap.add(item)，首先将item放入数组末尾，实现堆的上升，比较器是
    // 在此处定义的 comparePriority，优先级高的会往上升
    super.add(item);
    return this;
  }
  remove(item, customFindingComparator) {
    // 调用heap.remove(item, customFindingComparator)
    // 当将item对应索引替换为数组最后一个元素，然后分别实现堆上升和堆下沉
    super.remove(item, customFindingComparator);
    this.priorities.delete(item);
    return this;
  }
  changePriority(item, priority) {
    // 先删除在堆里面对应的item，再按照新的优先级加入堆ß
    this.remove(item, new Comparator(this.compareValue));
    this.add(item, priority);
    return this;
  }
  findByValue(item) {
    return this.find(item, new Comparator(this.compareValue));
  }
  hasValue(item) {
    return this.findByValue(item).length > 0;
  }
  // 实现一个比较器，默认比较器类似于下面的compareValue
  // 这儿我们要实现优先级的比较，会按照priority的大小来实现堆的顺序
  comparePriority(a, b) {
    if (this.priorities.get(a) === this.priorities.get(b)) {
      return 0;
    }
    return this.priorities.get(a) < this.priorities.get(b) ? -1 : 1;
  }
  compareValue(a, b) {
    if (a === b) {
      return 0;
    }
    return a < b ? -1 : 1;
  }
}